package com.kdg.proxy;


import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * Cglib代理
 * Created by kong on 2018/5/25.
 */
public class CglibProxy {

    public static void main(String[] args) {
        UserDaoImpl userDao = new UserDaoImpl();
        CglibProxyFactory cglibProxyFactory = new CglibProxyFactory(userDao);
        UserDaoImpl proxyInstance = (UserDaoImpl) cglibProxyFactory.getProxyInstance();
        proxyInstance.select();
        /**
         * Cglib代理：代理不需要实现接口的对象，也叫子类代理，
         *      它是在内存中构建一个子类对象从而实现对目标对象的扩展
         *      代理的类不能为final,否则报错
         *      目标对象的方法如果为final/static,那么就不会被拦截,即不会执行目标对象额外的业务方法.
         */
    }
}

/**
 * Cglib代理工厂
 */
class CglibProxyFactory implements MethodInterceptor {

    private Object target;

    public CglibProxyFactory(Object object) {
        this.target = object;
    }

    /**
     * 获取代理对象
     * @return
     */
    public Object getProxyInstance(){
        //1.工具类
        Enhancer enhancer = new Enhancer();
        //2.设置父类
        enhancer.setSuperclass(target.getClass());
        //3.设置回调函数
        enhancer.setCallback(this);
        //4.创建子类（代理对象）
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println(method.getName() + " is start...");
        System.out.println("代理拦截方法执行开始");
        Object invoke = method.invoke(target, objects);
        System.out.println("代理拦截方法执行结束");
        return invoke;
    }
}
